///////////////////////////////////////////////////////////////////////////////
//	FILENAME:	eTBookmarkBinder.m 
//	SUMMARY:	Appwide rendezvous point for bookmark management
//	SUPERCLASS:	Object
//	INTERFACE:	None
//	PROTOCOLS:	None
//	AUTHOR:		Rohit Khare
//	COPYRIGHT:	(c) 1994 California Institure of Technology, eText Project
///////////////////////////////////////////////////////////////////////////////
//  IMPLEMENTATION COMMENTS
//		We maintain a table of document-wide anchor tables; registration and
//	unregistration ensure consistency. Aside from lookup and query functions,
//	the Binder will offer to fill a matrix as used in a browser. There is only
//	one of these in the runtime space (this being an application whose runtime
//  is distributed over at most one virtual processor :)
///////////////////////////////////////////////////////////////////////////////
//	HISTORY
//	06/15/94:	Added dirty bit management. RK & TRZ
//	05/08/94:	Created. First actual implementation.
///////////////////////////////////////////////////////////////////////////////

#import "eTBookmarkBinder.h"

@implementation eTBookmarkBinder
//	id	docTable;
//	id	anchorTable;

+ new
{
	static eTBookmarkBinder *binder = nil;
	
	if (!binder) {
		binder = [[eTBookmarkBinder alloc] init];
	}
	return binder;	
}

- init
{
	[super init];
	dirtyBit = YES;
	docTable = [[HashTable alloc] initKeyDesc:"i" valueDesc:"@"];
	anchorTable = [[HashTable alloc] initKeyDesc:"i" valueDesc:"@"];
	return self;
}

- free
{
//	[docTable freeObjects];
//	[docTable free];
//	[anchorTable free];
//	return [super free];
	return self;
}

- registerBM:theBookmark ID:(long)anchorID inDoc:(long)docID
{
	id aTab;
	
	aTab = [docTable valueForKey:docID];
	if (!aTab)
		[docTable insertKey:docID value:(aTab = [[HashTable alloc] initKeyDesc:"i" valueDesc:"@"])]; 
	[aTab insertKey:anchorID value:theBookmark];
	[anchorTable insertKey:anchorID value:theBookmark];
	dirtyBit = YES;
	return self;
}

- unregisterBM:theBookmark ID:(long)anchorID inDoc:(long)docID
{
	id aTab;
	
	aTab = [docTable valueForKey:docID];
	if (aTab) [aTab removeKey:anchorID];
	[anchorTable removeKey:anchorID];
	//Q: did we just invalidate the browser? are we in trouble?
	dirtyBit = YES;
	return self;
}


- getBookmarks:theStorage inDoc:(long)docID
{	
	NXHashState state;
	long key;
	id value;
	id aTab;
	
	//iterate over states and populate the list
	aTab = [docTable valueForKey:docID];
	state = [aTab initState];
	while ([aTab nextState:&state key:(void **) &key value: (void**) &value])
		[theStorage addElement:&value];
	return self;
}

- bookmarkForID:(long)anchorID
{
	return ((id) [anchorTable valueForKey:anchorID]);
}

- (BOOL) isDirty
{
	if (dirtyBit) 
		{dirtyBit = NO; return YES;}
	else return NO;
}
@end